package cn.com.xuxiaowei.config;

import cn.com.xuxiaowei.model.DataSourceConfig;
import cn.com.xuxiaowei.properties.DynamicDataSourceProperties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xuxiaowei
 */
@Getter
@Configuration
public class MultipleDataSourceConfig {

	public static final String SQL = "SELECT `name`, url, driver_class_name, username, `password` FROM dd_data_dource_config";

	@Setter
	private Map<Object, Object> targetDataSources = new HashMap<>(8);

	@Setter
	private DataSource defaultTargetDataSource;

	@Setter
	private boolean lenientFallback;

	@Bean
	public MultipleDataSource multipleDataSource(DynamicDataSourceProperties dynamicDataSourceProperties) {

		String primary = dynamicDataSourceProperties.getPrimary();
		lenientFallback = dynamicDataSourceProperties.isLenientFallback();

		Map<String, DynamicDataSourceProperties.DataSourceProperty> datasource = dynamicDataSourceProperties
			.getDatasource();
		DynamicDataSourceProperties.DataSourceProperty dataSourceProperty = datasource.get(primary);

		defaultTargetDataSource = DataSourceBuilder.create()
			.url(dataSourceProperty.getUrl())
			.driverClassName(dataSourceProperty.getDriverClassName())
			.username(dataSourceProperty.getUsername())
			.password(dataSourceProperty.getPassword())
			.build();

		for (String key : datasource.keySet()) {
			DynamicDataSourceProperties.DataSourceProperty ds = datasource.get(key);

			String url = ds.getUrl();
			String driverClassName = ds.getDriverClassName();
			String username = ds.getUsername();
			String password = ds.getPassword();

			DataSource build = DataSourceBuilder.create()
				.driverClassName(driverClassName)
				.url(url)
				.username(username)
				.password(password)
				.build();

			targetDataSources.put(key, build);
		}

		MultipleDataSource multipleDataSource = new MultipleDataSource();

		JdbcTemplate jdbcTemplate = new JdbcTemplate(defaultTargetDataSource);
		List<DataSourceConfig> dataSourceConfigs = jdbcTemplate.query(SQL, (rs, rowNum) -> {
			DataSourceConfig dataSourceConfig = new DataSourceConfig();
			dataSourceConfig.setName(rs.getString("name"));
			dataSourceConfig.setUrl(rs.getString("url"));
			dataSourceConfig.setDriverClassName(rs.getString("driver_class_name"));
			dataSourceConfig.setUsername(rs.getString("username"));
			dataSourceConfig.setPassword(rs.getString("password"));
			return dataSourceConfig;
		});

		for (DataSourceConfig dataSourceConfig : dataSourceConfigs) {

			String name = dataSourceConfig.getName();
			String url = dataSourceConfig.getUrl();
			String driverClassName = dataSourceConfig.getDriverClassName();
			String username = dataSourceConfig.getUsername();
			String password = dataSourceConfig.getPassword();

			DataSource build = DataSourceBuilder.create()
				.driverClassName(driverClassName)
				.url(url)
				.username(username)
				.password(password)
				.build();

			targetDataSources.put(name, build);
		}

		multipleDataSource.setTargetDataSources(targetDataSources);
		multipleDataSource.setDefaultTargetDataSource(defaultTargetDataSource);
		multipleDataSource.setLenientFallback(lenientFallback);

		return multipleDataSource;
	}

}
